package com.zjj.shiro.service;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.sql.generator.Query;
import com.sql.generator.SQL;
import com.sql.generator.Service;
import com.zjj.util.CommonUtil;
import com.zjj.util.HibernateBasic;

@Component
public class ShiroServiceImpl implements ShiroService {

    @Autowired
    private SessionFactory sessionFactory;

	@Override
	public String login(String loginName, String passwordMD5) throws AuthenticationException {
		Query mainQuery = SQL.select("USER_ID,PHONE,PASSWORD");
		mainQuery.from("T_USER");
		mainQuery.where("PHONE=", loginName);

		Service service = new Service(mainQuery);
		service.useCustomResultTransformer();
		service.setDescription(ShiroServiceImpl.class + ".login");

		Map<String, Object> result = new HibernateBasic(sessionFactory).execute(service);
		if (CommonUtil.isInvalid(result)) {
			throw new AuthenticationException("服务器错误，请稍后重试！");
		}
		// 帐号不存在
		@SuppressWarnings("unchecked")
		List<Map<String, Object>> userInfoList = (List<Map<String, Object>>) result.get(mainQuery.getResultCallback());
		if (CollectionUtils.isEmpty(userInfoList)) {
			throw new AuthenticationException("用户名或者密码错误！");
		}
		// 帐号不唯一
		if (userInfoList.size() > 1) {
			throw new AuthenticationException("用户名或者密码错误！");
		}
		// 取出用户信息
		Map<String, Object> userInfo = userInfoList.get(0);
		String passwordFromDB = (String) userInfo.get("PASSWORD");
		String userId = userInfo.get("USER_ID") + ""; 

		// 密码是否正确
		boolean pass = passwordMD5.equals(passwordFromDB);
		if (!pass) {
			throw new AuthenticationException("用户名或者密码错误！");
		}
		return userId;
	}

	@Override
	public Set<String> getUserRoles(String userId) {
		Set<String> roleSet = new HashSet<String>();
		Query query = SQL.select("ur.ROLE_ID");
		query.from("t_shiro_user_role ur, t_shiro_role r");
		query.where("ur.user_id =", userId);
		query.and(SQL.columnRelationEquals("ur.role_id", "r.id"));
		query.and("ur.status =", 0);
		query.and("r.status =", 0);
		query.setProhibitDefaultLimit(true);

		Service service = new Service(query);
		service.useCustomResultTransformer();
		service.setDescription(ShiroServiceImpl.class + ".getUserRoles");
		Map<String, Object> result = new HibernateBasic(sessionFactory).execute(service);
		if (CommonUtil.isInvalid(result)) {
			return roleSet;
		}

		List<Map<String, Object>> roleList = (List<Map<String, Object>>) result.get(query.getResultCallback());
		if (CollectionUtils.isEmpty(roleList)) {
			return roleSet;
		}
		for (Map<String, Object> roleMap : roleList) {
			String roleId = roleMap.get("ROLE_ID").toString(); 
			roleSet.add(roleId);
		}
		return roleSet;
	}
	
	@Override
	public Set<String> getMenuButtonResources(Set<String> roles) {
		Set<String> resourceSet = new HashSet<String>();
		if (CollectionUtils.isEmpty(roles)) {
			return resourceSet;
		}
		Query query = SQL.select("R.VALUE");
		query.from("t_shiro_permission p, t_shiro_resource r");
		query.where(SQL.columnRelationEquals("p.resource_id", "r.id"));
		query.and("p.role_id in", roles);
		query.and("p.status =", 0);
		query.and("r.status =", 0);
		query.and("r.type =", 1);
		query.setProhibitDefaultLimit(true);

		Service service = new Service(query);
		service.useCustomResultTransformer();
		service.setDescription(ShiroServiceImpl.class + ".getMenuButtonResources");
		Map<String, Object> result = new HibernateBasic(sessionFactory).execute(service);
		if (CommonUtil.isInvalid(result)) {
			throw new RuntimeException("无法确定权限");
		}
		List<Map<String, Object>> resourceList = (List<Map<String, Object>>) result.get(query.getResultCallback());
		if (CollectionUtils.isEmpty(resourceList)) {
			return resourceSet;
		}
		for (Map<String, Object> resourceMap : resourceList) {
			String value = (String) resourceMap.get("VALUE"); // 权限值
			resourceSet.add(value);
		}
		return resourceSet;
	}
	
	@Override
	public String getUserType(String userId) {
		Query query = SQL.select("USER_TYPE");
		query.from("t_userinfo");
		query.where("user_id =", userId);

		Service service = new Service(query);
		service.useCustomResultTransformer();
		service.setDescription(ShiroService.class + ".getUserType");
		Map<String, Object> result = new HibernateBasic(sessionFactory).execute(service);
		if (CommonUtil.isInvalid(result)) {
			throw new RuntimeException("无法确定用户类型");
		}
		List<Map<String, Object>> userInfoList = (List<Map<String, Object>>) result.get(query.getResultCallback());
		Map<String, Object> userInfo = userInfoList.get(0);
		return (String) userInfo.get("USER_TYPE");
	}
	
	@Override
	public List<Map<String, Object>> queryAllResource(String status) {
		Query query = SQL.select("TYPE,VALUE,DESCRIPTION,URL");
		query.from("T_SHIRO_RESOURCE");
		if (StringUtils.isNotBlank(status)) {
			query.and("status=", status);
		}
		query.setProhibitDefaultLimit(true);

		Service service = new Service(query);
		service.useCustomResultTransformer();
		service.setDescription(ShiroServiceImpl.class + ".queryAllResource");
		Map<String, Object> result = new HibernateBasic(sessionFactory).execute(service);
		if (CommonUtil.isInvalid(result)) {
			return null;
		}
		List<Map<String, Object>> resourceList = (List<Map<String, Object>>) result.get(query.getResultCallback());
		if (CollectionUtils.isEmpty(resourceList)) {
			return null;
		}
		return resourceList;
	}

}
